package org.convallaria.system.biz.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.convallaria.system.biz.service.SecurityConfigService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.util.HashMap;
import java.util.Map;

/**
 * 安全配置服务实现
 * 
 * @author convallaria
 * @since 1.0.0
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SecurityConfigServiceImpl implements SecurityConfigService {

    private final RedisTemplate<String, String> redisTemplate;
    private final ObjectMapper objectMapper;

    private static final String CONFIG_PREFIX = "security:config:";
    private static final String SECURITY_CONFIG_KEY = CONFIG_PREFIX + "security";
    private static final String PASSWORD_POLICY_KEY = CONFIG_PREFIX + "password_policy";
    private static final String LOGIN_LIMIT_KEY = CONFIG_PREFIX + "login_limit";
    private static final String TOKEN_CONFIG_KEY = CONFIG_PREFIX + "token";

    @Override
    public SecurityConfig getSecurityConfig() {
        try {
            String configJson = redisTemplate.opsForValue().get(SECURITY_CONFIG_KEY);
            if (configJson != null) {
                return objectMapper.readValue(configJson, SecurityConfig.class);
            }
        } catch (JsonProcessingException e) {
            log.error("解析安全配置失败", e);
        }
        
        // 返回默认配置
        return new SecurityConfig();
    }

    @Override
    public void updateSecurityConfig(SecurityConfig config) {
        try {
            String configJson = objectMapper.writeValueAsString(config);
            redisTemplate.opsForValue().set(SECURITY_CONFIG_KEY, configJson);
            log.info("安全配置已更新");
        } catch (JsonProcessingException e) {
            log.error("更新安全配置失败", e);
        }
    }

    @Override
    public PasswordPolicyConfig getPasswordPolicyConfig() {
        try {
            String configJson = redisTemplate.opsForValue().get(PASSWORD_POLICY_KEY);
            if (configJson != null) {
                return objectMapper.readValue(configJson, PasswordPolicyConfig.class);
            }
        } catch (JsonProcessingException e) {
            log.error("解析密码策略配置失败", e);
        }
        
        // 返回默认配置
        return new PasswordPolicyConfig();
    }

    @Override
    public void updatePasswordPolicyConfig(PasswordPolicyConfig config) {
        try {
            String configJson = objectMapper.writeValueAsString(config);
            redisTemplate.opsForValue().set(PASSWORD_POLICY_KEY, configJson);
            log.info("密码策略配置已更新");
        } catch (JsonProcessingException e) {
            log.error("更新密码策略配置失败", e);
        }
    }

    @Override
    public LoginLimitConfig getLoginLimitConfig() {
        try {
            String configJson = redisTemplate.opsForValue().get(LOGIN_LIMIT_KEY);
            if (configJson != null) {
                return objectMapper.readValue(configJson, LoginLimitConfig.class);
            }
        } catch (JsonProcessingException e) {
            log.error("解析登录限制配置失败", e);
        }
        
        // 返回默认配置
        return new LoginLimitConfig();
    }

    @Override
    public void updateLoginLimitConfig(LoginLimitConfig config) {
        try {
            String configJson = objectMapper.writeValueAsString(config);
            redisTemplate.opsForValue().set(LOGIN_LIMIT_KEY, configJson);
            log.info("登录限制配置已更新");
        } catch (JsonProcessingException e) {
            log.error("更新登录限制配置失败", e);
        }
    }

    @Override
    public TokenConfig getTokenConfig() {
        try {
            String configJson = redisTemplate.opsForValue().get(TOKEN_CONFIG_KEY);
            if (configJson != null) {
                return objectMapper.readValue(configJson, TokenConfig.class);
            }
        } catch (JsonProcessingException e) {
            log.error("解析Token配置失败", e);
        }
        
        // 返回默认配置
        return new TokenConfig();
    }

    @Override
    public void updateTokenConfig(TokenConfig config) {
        try {
            String configJson = objectMapper.writeValueAsString(config);
            redisTemplate.opsForValue().set(TOKEN_CONFIG_KEY, configJson);
            log.info("Token配置已更新");
        } catch (JsonProcessingException e) {
            log.error("更新Token配置失败", e);
        }
    }

    @Override
    public String getConfigValue(String key) {
        return redisTemplate.opsForValue().get(CONFIG_PREFIX + key);
    }

    @Override
    public void setConfigValue(String key, String value) {
        redisTemplate.opsForValue().set(CONFIG_PREFIX + key, value);
        log.info("配置已更新: {} = {}", key, value);
    }

    @Override
    public Map<String, String> getAllConfigs() {
        Map<String, String> configs = new HashMap<>();
        
        try {
            // 获取所有配置键
            String pattern = CONFIG_PREFIX + "*";
            var keys = redisTemplate.keys(pattern);
            
            if (keys != null) {
                for (String key : keys) {
                    String value = redisTemplate.opsForValue().get(key);
                    if (value != null) {
                        String configKey = key.substring(CONFIG_PREFIX.length());
                        configs.put(configKey, value);
                    }
                }
            }
        } catch (Exception e) {
            log.error("获取所有配置失败", e);
        }
        
        return configs;
    }

    /**
     * 初始化默认配置
     */
    public void initializeDefaultConfigs() {
        try {
            // 初始化安全配置
            if (redisTemplate.opsForValue().get(SECURITY_CONFIG_KEY) == null) {
                updateSecurityConfig(new SecurityConfig());
            }
            
            // 初始化密码策略配置
            if (redisTemplate.opsForValue().get(PASSWORD_POLICY_KEY) == null) {
                updatePasswordPolicyConfig(new PasswordPolicyConfig());
            }
            
            // 初始化登录限制配置
            if (redisTemplate.opsForValue().get(LOGIN_LIMIT_KEY) == null) {
                updateLoginLimitConfig(new LoginLimitConfig());
            }
            
            // 初始化Token配置
            if (redisTemplate.opsForValue().get(TOKEN_CONFIG_KEY) == null) {
                updateTokenConfig(new TokenConfig());
            }
            
            log.info("默认安全配置已初始化");
        } catch (Exception e) {
            log.error("初始化默认配置失败", e);
        }
    }
}
